package com.jing.ads.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
import android.os.StatFs;
import android.provider.Settings;
import android.util.Log;
import android.widget.Toast;

import com.jing.ads.application.GlobalConstants;
import com.jing.ads.application.MD5;
import com.jing.ads.downloader.Constants;
import com.jing.ads.downloader.DownloadReceiver;
import com.jing.ads.downloader.DownloadService;
import com.jing.ads.downloader.Downloads;
import com.jing.ads.model.PushAppInfo.AppDetail;

public class GlobalUtil {

	private static final String TAG = GlobalUtil.class.getSimpleName();

	private static Toast sToast = null;

	public static final int PKG_STORED_INTERNAL = 0;
	public static final int PKG_STORED_EXTERNAL = 1;
	public static final int PKG_STOREPREF_AUTO = 0; // auto
	public static final int PKG_STOREPREF_INT = 1; // internalOnly
	public static final int PKG_STOREPREF_EXT = 2; // preferExternal

	public static final int NOT_ALLOW_INSTALL_NON_MARKET_APPS = 0;

	/**
	 * 鏄惁鍏佽瀹夎闈炵數瀛愬競鍦烘彁渚涚殑搴旂敤绋嬪簭銆�
	 * 
	 * @param context
	 * @return
	 */
	public static boolean allowInstallNonMarketApps(Context context) {
		int result = Settings.Secure.getInt(context.getContentResolver(),
				Settings.Secure.INSTALL_NON_MARKET_APPS,
				NOT_ALLOW_INSTALL_NON_MARKET_APPS);

		return (result == NOT_ALLOW_INSTALL_NON_MARKET_APPS) ? false : true;
	}

	public static PackageInfo getPackageInfo(PackageManager packageManager,
			String packageName) {
		PackageInfo ret = null;
		try {
			ret = packageManager.getPackageInfo(packageName, 0);
		} catch (NameNotFoundException e) {
			// e.printStackTrace();
		}
		return ret;
	}

	public static Intent getPackageLaunchIntent(Context context, String packageName) {
		PackageManager pm = context.getPackageManager();
		try {
			return pm.getLaunchIntentForPackage(packageName);
		} catch (Exception e) {
			return null;
		}
	}
	
	public static void shortToast(Context context, int resId) {
		if (sToast == null) {
			sToast = Toast.makeText(context, resId, Toast.LENGTH_SHORT);
		} else {
			sToast.setText(resId);
			sToast.setDuration(Toast.LENGTH_SHORT);
		}
		sToast.show();
	}

	public static void shortToast(Context context, String msg) {
		if (sToast == null) {
			sToast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
		} else {
			sToast.setText(msg);
			sToast.setDuration(Toast.LENGTH_SHORT);
		}
		sToast.show();
	}

	public static void longToast(Context context, int resId) {
		if (sToast == null) {
			sToast = Toast.makeText(context, resId, Toast.LENGTH_SHORT);
		} else {
			sToast.setText(resId);
			sToast.setDuration(Toast.LENGTH_LONG);
		}
		sToast.show();
	}

	public static void longToast(Context context, String msg) {
		if (sToast == null) {
			sToast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
		} else {
			sToast.setText(msg);
			sToast.setDuration(Toast.LENGTH_LONG);
		}
		sToast.show();
	}

	public static void cancelToast() {
		if (sToast != null) {
			sToast.cancel();
		}
	}

	public static boolean isSystemApp(ApplicationInfo appInfo) {

		return (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1;
	}

	public static boolean isSystemApp(PackageManager packageManager) {

		return isSystemApp(packageManager, GlobalConstants.PACKAGE_NAME);
	}

	public static boolean isSystemApp(PackageManager packageManager,
			String packageName) {
		PackageInfo packageInfo = getPackageInfo(packageManager, packageName);
		if ((packageInfo == null || packageInfo.applicationInfo == null)) {
			return false;
		}
		return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1;
	}

	public static String[] getInstalledAppPackages(
			PackageManager packageManager, boolean getSystemApp) {
		List<ApplicationInfo> list = packageManager.getInstalledApplications(0);
		if (list != null) {
			ArrayList<String> packages = new ArrayList<String>();
			for (int i = 0, size = list.size(); i < size; i++) {
				ApplicationInfo info = list.get(i);
				if (getSystemApp || !GlobalUtil.isSystemApp(info)) {
					String packageName = info.packageName;
					if (!packageName.contains("com.android")
							&& !packageName.contains("com.htc")
							&& !packageName.contains("com.miui")
							&& !packageName.contains("com.motorola")
							&& !packageName.contains("com.sonyericsson")
							&& !packageName.contains("com.sony")) {
						int versionCode = -1;
						try {
							PackageInfo packageInfo = packageManager
									.getPackageInfo(
											info.packageName,
											PackageManager.GET_UNINSTALLED_PACKAGES);
							versionCode = packageInfo.versionCode;
						} catch (NameNotFoundException e) {
							e.printStackTrace();
						}
						packages.add(packageName + ":" + versionCode);
					}
				}
			}
			String[] installedPackages = new String[packages.size()];
			packages.toArray(installedPackages);
			return installedPackages;
		}

		return null;
	}

	public static boolean isInstalledApp(Context context, String packageName) {
		if (context == null) {
			return false;
		}
		PackageManager pm = context.getPackageManager();
		List<ApplicationInfo> list = pm.getInstalledApplications(0);
		for (ApplicationInfo appInfo : list) {
			if (appInfo.packageName.equals(packageName)) {
				return true;
			}
		}
		return false;
	}

	public static String getAppName(PackageManager pm, String packageName) {
	        String name = "";
			try {
				name = pm.getPackageInfo(packageName, 0).applicationInfo.loadLabel(pm).toString();
			} catch (NameNotFoundException e) {
				e.printStackTrace();
			} 
	        return name;
	}
	
	public static void startInstall(Context context, File file) {
		if (!file.exists()) {
			return;
		}
		if (!allowInstallNonMarketApps(context)) {
			// TODO
		}
		Intent intent = new Intent();
		intent.setAction(Intent.ACTION_VIEW);
		intent.addCategory(Intent.CATEGORY_DEFAULT);
		intent.setDataAndType(Uri.fromFile(file), GlobalConstants.MIMETYPE_APK);
		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		context.startActivity(intent);
	}

	public static void startAppManagerActivity(final Context context,
			String pkgName) {
		Intent it = new Intent(Intent.ACTION_VIEW);

		it.setClassName("com.android.settings",
				"com.android.settings.InstalledAppDetails");
		it.putExtra("com.android.settings.ApplicationPkgName", pkgName);
		// this is for Andoriod 2.2(Froyo)
		it.putExtra("pkg", pkgName);

		List<ResolveInfo> acts = context.getPackageManager()
				.queryIntentActivities(it, 0);

		if (acts.size() > 0) {
			context.startActivity(it);
		} else {
			// for ginger bread
			it = new Intent("android.settings.APPLICATION_DETAILS_SETTINGS",
					Uri.fromParts("package", pkgName, null));

			acts = context.getPackageManager().queryIntentActivities(it, 0);

			if (acts.size() > 0) {
				context.startActivity(it);
			} else {
				Log.d(TAG, "Failed to resolve activity for InstalledAppDetails");
			}
		}
	}

	public static Intent getAppLaunchIntent(PackageManager packageManager,
			String packageName) {
		try {
			Intent intent = packageManager
					.getLaunchIntentForPackage(packageName);
			if (intent != null) {
				intent = intent.cloneFilter();
				intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
				return intent;
			}

			PackageInfo pkginfo = getPackageInfo(packageManager, packageName);
			if (pkginfo != null) {
				if (pkginfo.activities != null
						&& pkginfo.activities.length == 1) {
					intent = new Intent(Intent.ACTION_MAIN);
					intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
					intent.setClassName(pkginfo.packageName,
							pkginfo.activities[0].name);
					return intent;
				}
			}
		} catch (Exception e) {
			return null;
		}
		return null;
	}

	public static List<String> getHomeLauncher(Context context) {
		List<String> names = new ArrayList<String>();
		PackageManager packageManager = context.getPackageManager();
		Intent intent = new Intent(Intent.ACTION_MAIN);
		intent.addCategory(Intent.CATEGORY_HOME);
		List<ResolveInfo> resolveInfo = packageManager.queryIntentActivities(
				intent, PackageManager.MATCH_DEFAULT_ONLY);
		for (ResolveInfo ri : resolveInfo) {
			names.add(ri.activityInfo.packageName);
		}
		return names;
	}

	public static boolean isHome(Context context) {
		List<String> names = getHomeLauncher(context);
		ActivityManager mActivityManager = (ActivityManager) context
				.getSystemService(Context.ACTIVITY_SERVICE);
		List<RunningTaskInfo> rti = mActivityManager.getRunningTasks(1);
		String fpkn = rti.get(0).topActivity.getPackageName();
		for (String name : names) {
			if (name.equals(fpkn)) {
				return true;
			}
		}
		if (fpkn.equals(context.getPackageName())) {
			return true;
		}
		return false;
	}

	public static boolean isTaskRunning(Context context, String activityName) {
		try {
			ActivityManager activityManager = (ActivityManager) context
					.getSystemService(Context.ACTIVITY_SERVICE);
			List<RunningTaskInfo> runningTasks = activityManager
					.getRunningTasks(30);
			if (runningTasks != null) {
				for (int i = 0, size = runningTasks.size(); i < size; i++) {
					if (GlobalConstants.DEBUG) {
						Log.d(TAG,
								"runningTasks, i: "
										+ runningTasks.get(i).baseActivity
												.getClassName() + ": "
										+ activityName);
					}
					if (runningTasks.get(i).baseActivity.getClassName().equals(
							activityName)) {
						return true;
					}
				}
			}
		} catch (Exception e) {
		}

		return false;
	}

	public static boolean isServiceRunning(Context context, String serviceName) {
		try {
			ActivityManager activityManager = (ActivityManager) context
					.getSystemService(Context.ACTIVITY_SERVICE);
			ArrayList<RunningServiceInfo> runningService = (ArrayList<RunningServiceInfo>) activityManager
					.getRunningServices(30);
			if (runningService != null) {
				for (int i = 0, size = runningService.size(); i < size; i++) {
					if (runningService.get(i).service.getClassName().toString()
							.equals(serviceName)) {
						return true;
					}
				}
			}
		} catch (Exception e) {
		}

		return false;
	}

	public static boolean isDownloadStarted(ContentResolver contentResolver,
			int appId, String downloadUrl) {
		boolean result = false;
		Cursor cursor = null;
		if (appId >= 0) {
			cursor = contentResolver.query(
					Downloads.CONTENT_URI,
					new String[] { Downloads.COLUMN_STATUS },
					SQLUtil.getSelectionAnd(new String[] {
							Downloads.COLUMN_APP_ID, Downloads.COLUMN_URI }),
					new String[] { String.valueOf(appId), downloadUrl }, null);
		}

		if (cursor != null && cursor.moveToFirst()) {
			int status = cursor.getInt(0);
			if (status == Downloads.STATUS_RUNNING
					|| status == Downloads.STATUS_RUNNING_PAUSED
					|| status == Downloads.STATUS_PENDING
					|| status == Downloads.STATUS_PENDING_PAUSED) {
				result = true;
			}
		}
		if (cursor != null) {
			cursor.close();
		}

		return result;
	}

	public static boolean isDownloadCompleted(ContentResolver contentResolver,
			int appId, String downloadUrl) {
		boolean result = false;
		Cursor cursor = null;
		if (appId >= 0) {
			cursor = contentResolver.query(
					Downloads.CONTENT_URI,
					new String[] { Downloads.COLUMN_STATUS, Downloads._DATA },
					SQLUtil.getSelectionAnd(new String[] {
							Downloads.COLUMN_APP_ID, Downloads.COLUMN_URI }),
					new String[] { String.valueOf(appId), downloadUrl }, null);
		}

		if (cursor != null && cursor.moveToFirst()) {
			int status = cursor.getInt(0);
			String filePath = cursor.getString(1);
			if (status == Downloads.STATUS_SUCCESS
					&& new File(filePath).exists()) {
				result = true;
			}
		}
		if (cursor != null) {
			cursor.close();
		}

		return result;
	}

	public static void setAppDownloadStatus(ContentResolver contentResolver,
			AppDetail app) {
		Cursor cursor = null;
		try {
			cursor = contentResolver.query(Downloads.CONTENT_URI,
					new String[] { Downloads.COLUMN_STATUS,
							Downloads._DATA,
							Downloads.COLUMN_NOTIFICATION_EXTRAS,
							Downloads.COLUMN_CURRENT_BYTES, 
							Downloads.COLUMN_TITLE}, null, null,
					Downloads._ID);
			for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor
					.moveToNext()) {
				String pName = cursor.getString(2);
				if (app.packageName.contains(pName)) {
					int status = cursor.getInt(0);
					int current = cursor.getInt(3);
					String name = cursor.getString(4);
					String filePath = cursor.getString(1);
					if (status == Downloads.STATUS_RUNNING
							|| status == Downloads.STATUS_RUNNING_PAUSED
							|| status == Downloads.STATUS_PENDING
							|| status == Downloads.STATUS_PENDING_PAUSED) {
						app.downloadStatus = AppDetail.PAUSE;
						app.downloadCount = current;
						app.appName = name;
					} else if (status == Downloads.STATUS_SUCCESS
							&& new File(filePath).exists()) {
						app.downloadStatus = AppDetail.DOWNLOADED;
						app.filePath = filePath;
						app.appName = name;
					} else {
						app.downloadStatus = AppDetail.UNDOWNLOAD;
						app.appName = name;
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (cursor != null) {
				cursor.close();
			}
		}
	}

	public static boolean isSDCardMounted() {
		if (Environment.getExternalStorageState().equals(
				Environment.MEDIA_MOUNTED)) {
			return true;
		}

		return false;
	}

	/**
	 * 鑾峰緱sdcard 鍓╀綑绌洪棿瀛楄妭鏁�
	 * 
	 * @return byte
	 */
	public static long getSDCardFreespace() {
		File sdcardDir = Environment.getExternalStorageDirectory();
		StatFs sf = new StatFs(sdcardDir.getPath());
		long blockSize = sf.getBlockSize(); // block澶у皬
		long availCount = sf.getAvailableBlocks();

		return availCount * blockSize;
	}

	public static void startDownloadService(Context context, PackageManager pm) {
		ComponentName componentName = new ComponentName(context,
				DownloadReceiver.class);
		int state = pm.getComponentEnabledSetting(componentName);
		if (state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
			pm.setComponentEnabledSetting(componentName,
					PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
					PackageManager.DONT_KILL_APP);
		}

		if (!isServiceRunning(context, DownloadService.class.getName())) {
			context.startService(new Intent(context, DownloadService.class));
		}
	}

	public static String getClientVersion(Context context) {
		PackageInfo packageInfo = GlobalUtil.getPackageInfo(
				context.getPackageManager(), GlobalConstants.PACKAGE_NAME);
		String version = "";
		if (packageInfo != null) {
			version = packageInfo.versionCode + "|" + packageInfo.versionName;
		}
		return version;
	}

	public static int getClientVersionCode(Context context) {
		PackageInfo packageInfo = GlobalUtil.getPackageInfo(
				context.getPackageManager(), GlobalConstants.PACKAGE_NAME);
		int versionCode = 0;
		if (packageInfo != null) {
			versionCode = packageInfo.versionCode;
		}
		return versionCode;
	}

	public static String getClientVersionName(Context context) {
		PackageInfo packageInfo = GlobalUtil.getPackageInfo(
				context.getPackageManager(), GlobalConstants.PACKAGE_NAME);
		String versionName = "";
		if (packageInfo != null) {
			versionName = packageInfo.versionName;
		}
		return versionName;
	}

	public static String getAllApps(Context context) {
		PackageManager pm = context.getPackageManager();
		List<PackageInfo> lists = pm.getInstalledPackages(0);
		if (lists.isEmpty()) {
			return "";
		}
		try {
			JSONArray array = new JSONArray();
			for (PackageInfo info : lists) {
				if (info.applicationInfo.uid >= 10000) {
					JSONObject r = new JSONObject();
					r.put("package_name", info.packageName);
					r.put("version_name", info.versionName);
					r.put("version_code", info.versionCode);
					array.put(r);
				}
			}
			return array.toString();

		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}

	public static boolean isInQueue(String queue, long qTime) {
		long ct = System.currentTimeMillis();
		Calendar c = Calendar.getInstance();
		int hour = c.get(Calendar.HOUR_OF_DAY);
		long inter = ct - qTime;
		try {
			if (queue.contains(":")) {
				String[] temp = queue.split(":");
				String dd = temp[1];
				if (dd.contains("d")) {
					int index = dd.indexOf("d");
					String sqd = dd.substring(0, index);
					int sqi = Integer.valueOf(sqd);
					long limit = sqi * 3600 * 24 * 1000;
					if (inter >= limit) {
						String q = temp[0];
						String[] qtemp = q.split(",");
						for (String t : qtemp) {
							if (t.contains("-")) {
								String s = t.split("-")[0];
								String e = t.split("-")[1];
								int sd = Integer.valueOf(s);
								int ed = Integer.valueOf(e);
								if (hour >= sd) {
									return true;
								} else if (hour <= ed) {
									return true;
								}
							}
						}
					} else {
						return false;
					}
				}else if (dd.contains("m")) {
					int index = dd.indexOf("m");
					String s = dd.substring(0, index);
					int sqi = Integer.valueOf(s);
					long limit = sqi * 1000 * 60;
					if (inter >= limit) {
						return true;
					}
				}else if (dd.contains("h")) {
					int index = dd.indexOf("h");
					String s = dd.substring(0, index);
					int sqi = Integer.valueOf(s);
					long limit = sqi * 1000 * 3600;
					if (inter >= limit) {
						return true;
					}
				}
			}
		} catch (Exception e) {
			return true;
		}
		return false;
	}
	
	public static long getDownloadAPKSize(Context context, final String url) {
		String name = MD5.MD5Encode(url) + ".apk";
		String root = Environment.getExternalStorageDirectory().getPath();
		File base = new File(root + Constants.DEFAULT_DL_SUBDIR);
		if (!base.exists()) {
//			base.mkdirs();
			return 0l;
		}
		File apk = new File(base, name);
		if (apk.exists()) {
			return apk.length();
		}
		return 0l;
	}
	
	public static File isDownloadAPk(Context context, final String url) {
		String name = MD5.MD5Encode(url) + ".apk";
		String root = Environment.getExternalStorageDirectory().getPath();
		File base = new File(root + Constants.DEFAULT_DL_SUBDIR);
		if (!base.exists()) {
			base.mkdirs();
		}
		File apk = new File(base, name);
		
		return apk.exists() ? apk : null;
	}

	public static void downloadSelf(final Context context, final String url) {
		String name = MD5.MD5Encode(url) + ".apk";
		String root = Environment.getExternalStorageDirectory().getPath();
		File base = new File(root + Constants.DEFAULT_DL_SUBDIR);
		if (!base.exists()) {
			base.mkdirs();
		}
		final File apk = new File(base, name);
		if (apk.exists()) {
			return;
		}
		new Thread() {
			public void run() {
				HttpClient client = new DefaultHttpClient();
				HttpGet get = new HttpGet(url);
				HttpResponse response;
				FileOutputStream fileOutputStream = null;
				InputStream is = null;
				try {
					response = client.execute(get);
					HttpEntity entity = response.getEntity();
					is = entity.getContent();
					if (is != null) {
						fileOutputStream = new FileOutputStream(apk);

						byte[] buf = new byte[1024];
						int ch = -1;
						while ((ch = is.read(buf)) != -1) {
							fileOutputStream.write(buf, 0, ch);
						}
					}
					fileOutputStream.flush();
//					PreferenceUtil.putSharedString(context, "self_apk", url);
					startInstall(context, apk);
				} catch (ClientProtocolException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} finally {
					try {
						if (fileOutputStream != null) {
							fileOutputStream.close();
						}
						if (is != null) {
							is.close();
						}
						get.abort();
						client.getConnectionManager().shutdown();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}

		}.start();
	}
}
